Shiny.addCustomMessageHandler("choropleth_values", function(message) {

    var choropleth_data = message[0][1];
    var heatmap_data = message[1];
    var mesos_data = message[2];

    // Create dropdown menu
    var years = [2012, 2013, 2014, 2015, 2016, 2017];

    var margin = { top: 0, right: 0, bottom: 0, left: 0 },
	width = window.innerWidth * 0.3,
	height = window.innerHeight * 0.7;

    // Sizes for small multiples
    var swidth = window.innerWidth * 0.6,
	sheight = window.innerHeight * 0.2;

    var select = d3.select("#choropleth_dropdown_area")
	.append('select')
	.attr('class', 'year_select')
	.on('change', onchange);

    var options = select.selectAll('options')
	.data(years)
	.enter()
	.append('option')
	.text(function(d) { return d;});

    draw(choropleth_data);

    function onchange() {
	var selectValue = d3.select('.year_select')
	    .property('value');

	if (selectValue == "2012") {
	    draw(message[0][0]);
	} else if (selectValue == "2013") {
	    draw(message[0][1]);
	} else if (selectValue == "2014"){
	    draw(message[0][2]);
	} else if (selectValue == "2015") {
	    draw(message[0][3]);
	} else if (selectValue == "2016") {
	    draw(message[0][4]);
	} else if (selectValue == "2017") {
	    draw(message[0][5]);
	}
    }

    var tooltip = d3.select("body")
	.append("div")
	.style("position", "absolute")
	.style("z-index", "10")
	.style("visibility", "hidden")
	.style("color", "white")
	.style("padding", "8px")
	.style("background-color", "rgba(0, 0, 0, 0.75)")
	.style("border-radius", "6px")
	.style("font", "12px sans-serif")
	.text("tooltip");

    var projection = d3.geoEquirectangular();

    var path = d3.geoPath()
	.projection(projection);

    var x = d3.scaleLinear()
	.domain(choropleth_data.percentage)
	.rangeRound([600, 860]);

    var dataDomain = [];

    function getDomain (l) {
	/*for (var i = 0; i < l.length; i++){
	  dataDomain[i] = l[i * 3];
	  }
	  return dataDomain.sort(function(a, b){return (a - b);});*/

	var v = d3.max(l) / 9;
	return [v, v*2, v*3, v*4, v*5, v*6, v*7, v*8];
    }


    var color = d3.scaleThreshold()
	.domain(getDomain(choropleth_data.percentage)).range(d3.schemeBlues[9]);
    /*.range(['#fff7f3','#fde0dd','#fcc5c0','#fa9fb5',
      '#f768a1','#dd3497','#ae017e','#7a0177',
      '#49006a','#ffffff','#f0f0f0','#d9d9d9',
      '#bdbdbd','#969696','#737373','#525252',
      '#252525','#000000']);*/


    var choropleth =  d3.select("#choropleth_area")
	.append("svg")
	.attr("width", width)
	.attr("height", height);

    /*var smallMultiples = d3.select("#smallmultiples_area")
	.append("svg")
	.attr("width", swidth)
	.attr("height", sheight);*/

    var zooming = function(o) {
	var offset = [d3.event.transform.x, d3.event.transform.y];

	var newScale = d3.event.transform.k * 2000;

	projection.translate(offset)
	    .scale(newScale);

	choropleth.selectAll("path")
	    .style("stroke", "black")
	    .style("stroke-width", 1)
	    .attr("d", path);
    };

    var zoom = d3.zoom()
	.on("zoom", zooming);

    var center = projection([-12.1, -50.6]);

    var map = choropleth.append("g")
	.attr("id", "map")
	.call(zoom)
	.call(zoom.transform, d3.zoomIdentity
	      .translate(width*1.5, height/3)
	      .scale(0.25));
    //.translate(-center[0], -center[1]));

    /*var small = smallMultiples.append("g")
	.attr("id", "small");*/

    //invisible rect covering all svg, so we can drag anywhere
    map.append("rect")
	.attr("x", 0)
	.attr("y", 0)
	.attr("width", width)
	.attr("height", height)
	.attr("opacity", 0);



    function draw(dataset) {

	d3.select("#choropleth_area").selectAll("#painted").remove();

	d3.json("uf.json").then(function(json) {
	   // console.log(json);

	    for (var i = 0; i < dataset.uf.length; i++) {
		var dataState = dataset.uf[i];
		var dataValue = parseFloat(dataset.percentage[i]);

		for (var j = 0; j < json.features.length; j++) {
		    var jsonState = json.features[j].properties.NOME_UF;

		    if (dataState == jsonState) {
			json.features[j].properties.value = dataValue;
			break;
		    }
		}
	    }

	    map.selectAll("path")
		.data(json.features)
		.enter()
		.append("path")
		.attr("d", path).attr("id", "painted")
		.style("stroke", "black")
		.style("stroke-width", 1)
		.style("fill",function(d) {
		    var value = d.properties.value;
		    if (value) {
			return color(value);
		    } else {
			return "#ccc";
		    }
		})
		.on("mouseover", function(d){
		    d3.select(this).style("stroke", "orange")
			.style("stroke-width", 2);
		    tooltip.html(d.properties.NOME_UF);
		    return tooltip.style("visibility", "visible").style("opacity", 1);
		})
		.on("mouseout", function(d){
		    d3.select(this).style("stroke", "black")
			.style("stroke-width", 1);
		    tooltip.html(d.properties.NOME_UF);
		    return tooltip.style("visibility", "hidden").style("opacity", 1);
		}).on("mousemove", function() {
		    d3.select(this)
			.style("stroke", "orange")
			.style("stroke-width", "1px");
		    return tooltip.style("top",(d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px");
		})
		.on("click", function(d) {
		    drawSmallMultiples(d, mesos_data);
		    //From heatmap.js
		    drawHeatMaps(heatmap_data, d.properties.NOME_UF);
		});

	});
    }

    //Draw isolated states
    function drawSmallMultiples (location, mesos_data) {
	d3.select("#smallmultiples_container").selectAll("svg").remove();
	d3.select("#heatmap_stripes_area").selectAll("svg").remove();

	var locationSet = [];

	d3.json("mesorregiao.json").then(function(json) {

	    var ufLocation = location.properties.NOME_UF;

	    for (var j = 0; j < json.features.length; j++) {

		var jsonState = json.features[j].properties.UF;

		if (ufLocation == jsonState) {
		    locationSet.push(json.features[j]);
		}
	    }

	    var spath = d3.geoPath()
		.projection(projection
			    .fitExtent([[0, 0], [swidth/6*0.8, sheight*0.8]], location));

	    for(var i = 0; i < 6; i++) {
		var small = d3.select("#sm20"+(i+12)+"_area")
		    .append("svg")
		    .attr("width", swidth/6)
		    .attr("height", sheight);

		var sm = small.append("g")
		    .attr("id", "small"+(i+12));

		sm.selectAll("path")
		    .data(locationSet)
		    .enter()
		    .append("path")
		    .attr("d", spath)
		    .style("stroke", "black")
		    .style("stroke-width", 1)
		    .style("fill", function(d) {
			var value;
			for (var j = 0; j < mesos_data[i].mesorregiao.length; j++) {

			    if (d.properties.MESO.toLowerCase() == mesos_data[i].mesorregiao[j].toLowerCase()) {
				value = mesos_data[i].percentage[j];
			    }
			}

			if (value) {
			    return color(value);
			} else {
			    return "#ccc";
			}
		    }).on("mouseover", function(d){
			d3.select(this).style("stroke", "orange")
			    .style("stroke-width", 2);
			tooltip.html(d.properties.MESO);
			return tooltip.style("visibility", "visible").style("opacity", 1);})
		    .on("mouseout", function(d){
			d3.select(this).style("stroke", "black")
			    .style("stroke-width", 1);
			tooltip.html(d.properties.MESO);
			return tooltip.style("visibility", "hidden").style("opacity", 1);
		    })
		    .on("mousemove", function() {
			d3.select(this)
			    .style("stroke", "orange")
			    .style("stroke-width", "1px");
			return tooltip.style("top",(d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px");
		    });
	    }
	});

    }


});
